package com.jzt.gateway.task;

import com.jzt.gateway.GlobalConstant;
import com.jzt.gateway.config.AuthConfig;
import com.jzt.gateway.config.ServersConfig;
import com.jzt.gateway.entity.AccountRegister;
import com.jzt.gateway.service.LoginService;
import com.jzt.gateway.utils.ExceptionUtils;
import com.jzt.gateway.utils.HttpUtils;
import com.jzt.gateway.utils.UrlPathUtils;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.config.GatewayProperties;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.List;
import java.util.Objects;

/**
 * 作者：lizw <br/>
 * 创建时间：2020/07/02 16:39 <br/>
 */
@Component
@Slf4j
public class AccountRegisterTask {
    @Autowired
    private ServersConfig serversConfig;
    @Autowired
    private GatewayProperties gatewayProperties;
    @Autowired
    private LoginService loginService;

    @Scheduled(initialDelay = 1000 * 10, fixedDelay = 1000 * 3)
    public void retryRegister() {
        if (!serversConfig.isEnableRegisterRetry()) {
            return;
        }
        long startTime = System.currentTimeMillis();
        log.info("[账号注册重试任务] - 开始...");
        List<AccountRegister> registerList = loginService.findNeedRetry();
        log.info("[账号注册重试任务] - 需要重试账号数量: {}", registerList.size());
        for (AccountRegister accountRegister : registerList) {
            try {
                log.info("[账号注册重试任务] - 当前重试: OneId={} | Platform={}", accountRegister.getOneId(), accountRegister.getPlatform());
                doRegister(accountRegister);
            } catch (Exception e) {
                loginService.addRetryCount(accountRegister);
                log.info("[账号注册重试任务] - 重试失败: OneId={} | Platform={}", accountRegister.getOneId(), accountRegister.getPlatform(), e);
            }
        }
        long useTime = System.currentTimeMillis() - startTime;
        log.info("[账号注册重试任务] - 完成，耗时: {}ms", useTime);
    }

    public void doRegister(AccountRegister accountRegister) {
        AuthConfig authConfig = serversConfig.getAuthConfig(accountRegister.getPlatform());
        if (authConfig == null) {
            throw new RuntimeException("AuthConfig 为空");
        }
        if (gatewayProperties.getRoutes() == null) {
            throw new RuntimeException("Routes 为空");
        }
        String uri = null;
        for (RouteDefinition route : gatewayProperties.getRoutes()) {
            if (Objects.equals(accountRegister.getPlatform(), route.getId())) {
                uri = StringUtils.trim(route.getUri().toString());
                break;
            }
        }
        if (StringUtils.isBlank(uri)) {
            throw new RuntimeException("Routes uri 为空");
        }
        // 发送请求
        final Request.Builder builder = new Request.Builder();
        builder.addHeader(GlobalConstant.GATEWAY_ONE_ID_NAME, accountRegister.getOneId());
        String url = UrlPathUtils.connectPath(uri, authConfig.getRegisterPath()) + "?" + accountRegister.getHttpQueryStr();
        HttpUrl httpUrl = HttpUrl.parse(url);
        if (httpUrl == null) {
            throw new RuntimeException("url参数错误");
        }
        builder.url(httpUrl);
        RequestBody requestBody = null;
        if (StringUtils.isNotBlank(accountRegister.getHttpBody())) {
            requestBody = RequestBody.create(MediaType.parse(HttpUtils.MediaType_Json), accountRegister.getHttpBody());
        }
        builder.method(StringUtils.upperCase(accountRegister.getHttpMethod()), requestBody);
        Response response = HttpUtils.execute(HttpUtils.getInner().getOkHttpClient(), builder.build());
        if (response == null) {
            throw new RuntimeException("Response 为空");
        }
        String userAgentId = response.header(GlobalConstant.GATEWAY_USER_AGENT_ID_NAME);
        String body = null;
        ResponseBody responseBody = response.body();
        if (responseBody != null) {
            try {
                body = responseBody.string();
            } catch (IOException e) {
                throw ExceptionUtils.unchecked(e);
            }
        }
        accountRegister.setUserAgentId(userAgentId);
        accountRegister.setHttpRes(body);
        loginService.registerRetrySuccess(accountRegister);
    }
}
